package com.itheima.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 将 权限校验的逻辑 抽取到这个类里面来写
 */
@Component

@Aspect
public class AuthorityAspect implements Ordered {
    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }










    //表达式
    //@Before("execution( * com.itheima.controller.AccountController.*(..))")
    //在目标方法之前运行
    public void check(JoinPoint jp){
        //我现在是在哪个方法之前运行的
        Object target = jp.getTarget();
        System.out.println("原来我们在改变是:"+target);
        //获取代理方法运行时候 用户传递实际参数
        Object[] args = jp.getArgs();
        System.out.println("实际参数:"+ Arrays.toString(args));

        //正在改变方法本身
        //方法签名  描述方法用的对象
        Signature signature = jp.getSignature();
        String name = signature.getName();
        System.out.println("方法名:"+name);

        System.out.println("权限校验");
    }
    //@After("execution( * com.itheima.controller.AccountController.*(..))")
    public void after(){
        System.out.println("我是方法after的代码~~~~~~~~~~~~~~~~~~");
    }
    //@AfterReturning("execution( * com.itheima.controller.AccountController.*(..))")
    public void afterReturning(){
        System.out.println("我是方法AfterReturning的代码~~~~~~~~~~~~~~~~~~");
    }
    //@AfterThrowing("execution( * com.itheima.controller.AccountController.*(..))")
    public void afterThrowing(){
        System.out.println("我是方法AfterThrowing的代码~~~~~~~~~~~~~~~~~~");
    }


    @Pointcut("execution( * com.itheima.controller.AccountController.*(..))")
    public void pt(){}





    //环绕增强
    @Around("pt()")
    public Object around(ProceedingJoinPoint joinPoint){

        //返回值
        Object result=null;

        try {
            //System.out.println("之前");
            System.out.println("我是~~~~~~~~~~~AuthorityAspect");
            System.out.println("权限校验");

            //业务代码...

            //调用这个方法时候  底层就会取出 方法对象参数对象 目标对象 method.invoke(目标,参数)
            result=joinPoint.proceed();



            //afterReturning
            //System.out.println("正确之后");
        }catch (Throwable e){
            //afterThrowing
            System.out.println("异常之后");
        }finally {
            //after
            //System.out.println("最终!!!");

        }

        return result;


    }






    public void template(){

        try {
            //before

            //业务代码...

            //afterReturning
        }catch (Exception e){
            //afterThrowing
        }finally {
            //after
        }
    }


}
